package de.htwg.memory;

import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

/**
 * this represent the connection class, which is necessary for the communication between android app and webserver
 * IMPORTANT: more than one communication instance will destroy the session in the webserver 
 *  
 * @author Benjamin Moellerke <bemoelle@googlemail.com>
 * @version V1.0 06-06-2012
 * 
 */
public final class Connection implements IConnection {
	
	private HttpClient client;
	
	//url were the webserver is located
	//use the alias 10.0.2.2 to referto the host computer's loopback interface
	private String url = "http://www.spieldose.ch/memory/memory.php";
	private HttpPost request = new HttpPost(url);
	private boolean validMemory = false;
	
	/**
	 * contructor
	 */
	public Connection() {
        HttpParams httpParams = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
        HttpConnectionParams.setSoTimeout(httpParams, 5000);
        client = new DefaultHttpClient(httpParams);
	}
		
	/**
	 * @param parentData  contains parameter for the webserver for exmaple: 
	 * { "action": "move", "params": {"firstCard": 4, "secondCard":5 } }
	 * { "action": "create", "params": {"row": 4, "column":5 } }
	 * @return a jsonAraay which have the response answer from webserver
  	 * @throws JSONException from JSON
	 * @throws JSONException  execute()
	 */
	private JSONObject request(JSONObject parentData) throws JSONException, IOException {
		
		JSONObject result = null;

        request.setEntity(new ByteArrayEntity(parentData.toString().getBytes("UTF8")));
        
        HttpResponse response = client.execute(request);
        StatusLine status = response.getStatusLine();
        Integer statusCode = status.getStatusCode();
        Log.d("StatusCode", statusCode.toString());
        
        if (statusCode == 200) {
        	HttpEntity entity = response.getEntity();
        	String ret = EntityUtils.toString(entity);
        	Log.d("result", ret);
        	result = new JSONObject(ret);
        }
        
        String re = result.getString("result");
        
        if(re.equals("error")) {
        	return null;
        }
        else {
        	return result;
        }
	}
		
  	/* (non-Javadoc)
	 * @see de.htwg.memory.IConnection#readMemory(int, int)
	 */
    public JSONArray readMemory(int row, int col) throws JSONException, IOException {
 	
    	JSONObject object = null;
    	
    	JSONObject parentData = new JSONObject();
    	parentData.put("action", "create");
    	
    	JSONObject childData = new JSONObject();
    	childData.put("row", Integer.valueOf(row));
    	childData.put("column", Integer.valueOf(col));
    	
       	parentData.put("params", childData);

       	//call request function and return the result
       	object = request(parentData);
       		
       	if(object == null) {
       		return null;
       	}
       	else {
       		validMemory = true;
       		return object.getJSONArray("result");
       	}
	}
   
    /* (non-Javadoc)
	 * @see de.htwg.memory.IConnection#readCardState(int, int)
	 */
	public int readCardState(int firstCard, int secondCard) throws JSONException, IOException {
		
		if(validMemory) {
			JSONObject object = null;
			
			JSONObject parentData = new JSONObject();
	    	parentData.put("action", "move");
	    	
	    	JSONObject childData = new JSONObject();
	    	childData.put("firstCard", Integer.valueOf(firstCard));
	    	childData.put("secondCard", Integer.valueOf(secondCard));
	    	
	       	parentData.put("params", childData);
	
	       	//call request function and return the result
	       	object = request(parentData);
	       	
	       	return object.getInt("result");
	       	
		}
		else {
			return -1;
		}
			
	}

}
